import { BrowserClient } from '@slardar/web';
import { nonEmpty } from '@/utils/non-empty';
import { createMinimalBrowserClient } from '@slardar/web/cn/minimal';
import { customPlugin } from '@slardar/integrations/dist/custom';
import { jsErrorPlugin } from '@slardar/integrations/dist/jsError';
import { EventNameMap, ErrorNameMap } from '@/constants';
import { ApiTrackReporter, CustomReporter, ReportContent, EventName, ErrorName } from '../types';
import { transform } from '@/utils/format-report-info';

interface ReporterOptions {
  biz_id?: string;
  env: string;
  slardar?: BrowserClient;
  options?: CustomReporter;
}
export class Reporter implements ApiTrackReporter {
  private slardarClient?: BrowserClient;
  private hostClient?: BrowserClient;
  private env: {
    biz_id?: string;
    env: string;
  };

  baseInfo: Record<string, string>;
  private customReport?: CustomReporter;
  constructor({ biz_id, env, slardar, options }: ReporterOptions) {
    this.env = { biz_id, env };
    this.baseInfo = {};
    this.customReport = options;
    this.hostClient = slardar;
    this.slardarClient = createMinimalBrowserClient();
    this.slardarClient.init({
      bid: 'api_track',
      env: env,
      plugins: {
        jsError: {
          onerror: false,
          onunhandledrejection: false,
        },
      },
      integrations: [jsErrorPlugin(), customPlugin()],
    });
    this.slardarClient.start();
  }

  setBaseInfo(baseInfo: Record<string, unknown>) {
    this.baseInfo = transform(nonEmpty(baseInfo));
  }

  sendLog(eventName: EventName | string, extra?: ReportContent<unknown>) {
    const reportName: string = typeof eventName === 'string' ? eventName : EventNameMap[eventName];
    const { categories, metrics } = extra || {};
    const reportInfo = nonEmpty({
      categories: transform(nonEmpty({ ...this.env, ...this.baseInfo, ...categories })),
      metrics,
    });

    this.customReport?.sendLog(reportName, reportInfo);

    this.hostClient?.sendEvent?.({
      name: reportName,
      ...reportInfo,
    });
    this.slardarClient?.sendEvent?.({
      name: reportName,
      ...reportInfo,
    });
  }

  reportError(errorName: ErrorName, extra: Record<string, string>) {
    const reportName: string = ErrorNameMap[errorName];
    const reportInfo = { ...this.env, ...this.baseInfo, ...extra };
    this.customReport?.reportError(reportName, reportInfo);
    this.hostClient?.captureException?.(reportName, reportInfo);
    this.slardarClient?.captureException?.(reportName, reportInfo);
  }
}
